package main

import (
	"bufio"
	"context"
	"flag"
	"fmt"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"io"
	"log"
	"os"
	"strconv"
	"stream_file_c/pb"
	"time"
)

const (
	defaultOrder = "input"
	defaultFile  = "imgs/1.jpg"
)

var orderName = flag.String("order", defaultOrder, "Name to order")
var fileName = flag.String("file", defaultFile, "Name to file")

func main() {
	flag.Parse()
	//拨号到server
	conn, err := grpc.Dial(":8896", grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		log.Printf("grpc.Dial failed,err:%v\n", err)
		return
	}
	defer conn.Close()
	//创建客户端
	sc := pb.NewFileClient(conn)
	runFileUpload(sc)
}
func runFileUpload(c pb.FileClient) {
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
	defer cancel()
	// 双向流模式
	stream, err := c.UploadFile(ctx)
	if err != nil {
		log.Fatalf("c.BidiHello failed, err: %v", err)
	}
	waitc := make(chan struct{})
	go func() {
		for {
			// 接收服务端返回的响应
			in, err := stream.Recv()
			if err == io.EOF {
				// read done.
				close(waitc)
				return
			}
			if err != nil {
				log.Fatalf("c.BidiHello stream.Recv() failed, err: %v", err)
			}
			fmt.Printf("服务器：%s\n", in.GetReply())
		}
	}()
	fmt.Println("请输入文件")
	cmd, fileInfo := orderName, fileName
	fmt.Println("cmd", cmd)
	fmt.Println("fileInfo", fileInfo)
	switch *cmd {
	case "input":
		upload(stream, *fileInfo)
	}
	stream.CloseSend()
	<-waitc
}
func upload(stream pb.File_UploadFileClient, fileInfo string) {
	fmt.Println("upload", fileInfo)
	//获取文件信息
	info, err := os.Stat(fileInfo)
	if err != nil {
		fmt.Println("upload,err", err)
	}
	name := info.Name()
	size := info.Size()
	//fmt.Println("name", name)
	//fmt.Println("size", size)
	//将文件名和文件大小传给server
	//格式:命令&name&size
	//int64转化为string
	sizeString := strconv.FormatInt(size, 10)
	infos := "input&" + name + "&" + sizeString
	if err := stream.Send(&pb.UploadRequest{Other: infos}); err != nil {
		log.Fatalf("c.BidiHello stream.Send(%v) failed: %v", infos, err)
	}
	//time.Sleep(time.Second)
	//打开文件
	uploadFile, _ := os.Open(fileInfo)
	//读取文件
	reader := bufio.NewReader(uploadFile)
	//循环上传
	for {
		//一行行读取
		line, err := reader.ReadBytes('\n')
		// 将获取到的数据发送至服务端
		if err := stream.Send(&pb.UploadRequest{Line: line}); err != nil {
			log.Fatalf("c.BidiHello stream.Send(%v) failed: %v", line, err)
		}
		if err == io.EOF {
			break
		}
	}
	fmt.Println("文件上传成功")
}
